// 使用管道

#include <iostream>
#include <cassert>
#include <cerrno>
#include <string>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
using namespace std;

int main()
{
    // 1、创建管道
    int pipefd[2] = {0};
    int ret = pipe(pipefd); // 打开管道
    if (ret == -1)
    {
        cout << "pipe fail! " << strerror(errno) << endl;
        return 1;
    }

    cout << "pipefd[0]: " << pipefd[0] << endl;
    cout << "pipefd[0]: " << pipefd[1] << endl;

    // 2、创建子进程
    pid_t id = fork();
    assert(id != -1);
    (void)id;

    // 此时规定：父进程写入、子进程读取

    if (id == 0)
    {
        // 子进程内
        // 3、关闭不需要的 fd
        close(pipefd[1]); // 关闭写，只读

        // 4、开始通信
        char buff[1024] = "0";
        while (true)
        {
            int n = read(pipefd[0], buff, sizeof(buff) - 1);
            if (n > 0)
            {
                buff[n] = '\0';
                cout << buff << endl;
            }
        }

        close(pipefd[0]); // 读也要关闭
        exit(-1);         // 子进程终止
    }

    // 3、关闭不需要的 fd
    close(pipefd[0]); // 关闭读取，只写入

    // 4、开始通信
    string str = "Hello! I am your father";
    int cnt = 1;
    char buff[1024] = "0"; // 缓冲区
    while (true)
    {
        snprintf(buff, sizeof buff, "%s %d PID:%d\n", str.c_str(), cnt, getpid());
        write(pipefd[1], buff, strlen(buff));
        cnt++;
        sleep(1);
    }

    close(pipefd[0]); // 写也要关闭
    return 0;
}
